package framework.util.controller;

import framework.bo.SysRole;
import framework.bo.SysUser;
import framework.bo.SysUserRole;
import framework.common.ResponseVo;
import framework.service.SysRoleService;
import framework.service.SysUserRoleService;
import framework.service.SysUserService;
import framework.util._EmailUtil;
import framework.util._PropertyUtil;
import framework.util.layui._LayuiUtil;
import framework.util.queryFilter.service.impl.QueryFilter;
import framework.util.queryFilter.vo.Where;
import framework.util.shiro._ShiroUtil;
import frameworkExt.util.controller.BaseControllerExt;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 用于校验用户登录
 *
 * @author 吴宇亮
 * @date 2018年12月19日
 */
@RequestMapping("/Login.do")
@Controller
public class LoginController extends BaseControllerExt {

    /** 服务器首页访问IP **/
	public static final String SERVER_IP;
	static{
		SERVER_IP = _PropertyUtil.propertiesMap.get(_PropertyUtil.FRAMEWORK_PROPERTIES).getProperty("serverIp");
	}
	/** 账号验证码缓存map **/
	private static final Map<String, String> verificationCodeMap = new HashMap<>();

	@Resource
	private SysUserService sysUserService;
	@Resource
	private SysRoleService sysRoleService;
	@Resource
	private SysUserRoleService sysUserRoleService;

	@RequestMapping(params = "method=printSession")
	public void printSession(HttpServletRequest request){
		System.out.println(request.getSession().getId());
		System.out.println(request.getSession().hashCode());
		System.out.println(request.getSession().getAttribute("currentUser"));
		System.out.println();

		Subject subject = SecurityUtils.getSubject();
		System.out.println(subject.getSession().getId());
		System.out.println(subject.getSession().hashCode());
		System.out.println(subject.getSession().getAttribute("currentUser"));
        System.out.println();

        SysUser currentUser = _ShiroUtil.getCurrentUser();
        System.out.println(currentUser);
        System.out.println("-----------------------------");
	}

	@RequestMapping(params = "method=logout")
	public void logout(HttpServletResponse response){
		try {
			//取消自动登陆
			Cookie autoLoginCookie = new Cookie("autoLogin", "\"false\"");
			autoLoginCookie.setPath(SERVER_IP + "/loginRegister");
			autoLoginCookie.setMaxAge(0);
			response.addCookie(autoLoginCookie);
			//登出
			Subject subject = SecurityUtils.getSubject();
			subject.logout();
			response.sendRedirect(SERVER_IP);
		} catch (IOException e) {
			log.error("", e);
		}
	}

	@ResponseBody
	@RequestMapping(params = "method=login", method = {RequestMethod.POST})
	public ResponseVo login(HttpServletRequest request, HttpServletResponse response) {
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		String autoLogin = request.getParameter("autoLogin");
		if(StringUtils.isAnyBlank(account, password)){
			return sendFail("账号 或 密码 不能为空");
		}

		//将登陆账号保存在cookie中（保存一年）
		Cookie loginAccount = new Cookie("loginAccount", account);
		loginAccount.setMaxAge(60 * 24 * 365);
		loginAccount.setPath(SERVER_IP + "/loginRegister");
		response.addCookie(loginAccount);
		//七天内自动登陆
		Cookie autoLoginCookie = new Cookie("autoLogin", "true");
		autoLoginCookie.setPath(SERVER_IP + "/loginRegister");
		autoLoginCookie.setMaxAge(StringUtils.isBlank(autoLogin) ? 0 : 60 * 24 * 7);
		response.addCookie(autoLoginCookie);

		Subject currentUser = SecurityUtils.getSubject();
		try {
			//如果是第一次登陆（没有RememberMe）
			if (!currentUser.isAuthenticated()) {
				//校验账号密码
				UsernamePasswordToken token = new UsernamePasswordToken(account, password);
				//登陆
				if(StringUtils.isNoneBlank(autoLogin)){
					token.setRememberMe(true);
				}
				currentUser.login(token);
			//通过RememberMe登陆，此时有可能有旧账号没注销的情况下，直接登陆新账号
			}else{
				String oldAccount = getCurrentUser().getAccount();
				//旧账号没注销的情况下，直接登陆新账号
				if(!account.equals(oldAccount)){
					//注销旧账号
					currentUser.logout();
					//重新验证新账号
					UsernamePasswordToken token = new UsernamePasswordToken(account, password);
					//登陆
					token.setRememberMe(true);
					currentUser.login(token);
				}
			}
		} catch (UnsupportedTokenException e) {
			return sendFail("用户 或 密码 错误");
		} catch (AuthenticationException e) {
			return sendFail("验证错误");
		}

		//返回响应
		return sendSuccess("登录成功");
	}

	@ResponseBody
	@RequestMapping(params = "method=sendVerificationCode", method = {RequestMethod.POST})
	public ResponseVo sendVerificationCode(@Param("account") String account, HttpSession session){
		if(StringUtils.isAnyBlank(account)){
			return sendFail("请输入正确的账号（账号为QQ邮箱）");
		}else if(-1 == account.lastIndexOf("@qq.com")){
			return sendFail("请输入正确的账号（账号为QQ邮箱）");
		}

		//acount不能相同
		QueryFilter filter = new QueryFilter(_LayuiUtil.FIRST_PAGE, Integer.MAX_VALUE);
		filter.where(SysUser.ACCOUNT, Where.eq, account);
		if(0 != sysUserService.getCount(filter)){
			return sendFail("账号【" + account + "】已存在，请换一个账号在进行注册！");
		}

		String uuid = UUID.randomUUID().toString();
		session.setAttribute("registerVerificationCode", uuid);
		_EmailUtil.sendQQEmail(account, "裕兴昌收银系统验证码", "您好！欢迎注册裕兴昌收银系统！您的验证码为：" + uuid);
		return sendSuccess("发送成功！");
	}

	@ResponseBody
	@RequestMapping(params = "method=register", method = {RequestMethod.POST})
	public ResponseVo register(HttpServletRequest request, HttpSession session){
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		String verificationCode = request.getParameter("verificationCode");
		if(StringUtils.isAnyBlank(account, password)){
			return sendFail("账号 或 密码 不能为空");
		}else if(StringUtils.isAnyBlank(verificationCode)){
			return sendFail("请输入验证码");
		}

		Object registerVerificationCode = session.getAttribute("registerVerificationCode");
		if(null == registerVerificationCode || "".equals(registerVerificationCode.toString())){
			return sendFail("请点击【发送验证码】按钮，获取验证码后在进行注册！");
		}else if(!verificationCode.equals(registerVerificationCode.toString())){
			return sendFail("验证码错误！");
		}

		//acount不能相同
		QueryFilter filter = new QueryFilter(_LayuiUtil.FIRST_PAGE, Integer.MAX_VALUE);
		filter.where(SysUser.ACCOUNT, Where.eq, account);
		if(0 != sysUserService.getCount(filter)){
			return sendFail("账号【" + account + "】已存在，请换一个账号在进行注册！");
		}

		SysUser sysUser = new SysUser();
		sysUser.setAccount(account);
		sysUser.setCname(account);
		sysUser.setPassword(_ShiroUtil.encodeSalt(password, account));
		sysUserService.add(sysUser);

		//查询游客的角色id
		QueryFilter roleFilter = new QueryFilter(_LayuiUtil.FIRST_PAGE, Integer.MAX_VALUE);
		roleFilter.where(SysRole.CNAME, Where.eq, "游客");
		SysRole sysRole = sysRoleService.get(roleFilter);
		//保存该用户的角色
		SysUserRole userRole = new SysUserRole();
		userRole.setUserLid(sysUser.getLid());
		userRole.setRoleLid(sysRole.getLid());
		sysUserRoleService.add(userRole);

		return sendSuccess("注册成功");
	}
	
}
